package plg.grupo1.Lexico.guiApp;



import java.awt.Dimension;
import java.awt.Label;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Vector;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileFilter;

import plg.grupo1.Lexico.StateMachineHierarchy.Contexto;
import plg.grupo1.Lexico.StateMachineHierarchy.State0;
import plg.grupo1.Lexico.TokenHierarchy.Token;
import plg.grupo1.Lexico.TokenHierarchy.TokenError;
import plg.grupo1.Sintactico.SemanticoInicio;


public class TokenReaderGui extends JFrame implements ListSelectionListener{

	private static final long serialVersionUID = -7890074229083011965L;
	private JMenuBar jMenuBar1 = new javax.swing.JMenuBar();
	private PanelSuperiorGui panelSuperior;
	private static JTextArea panelErrores;
	private JFileChooser chooser;
	//Memoriza el ultimo path abierto por JfileChooser
	private File lastFileOpen = null;
	//filtro para el fileChooser
	private FileFilter filterFiles = new ExtensionFileFilter("TXT and RTF",new String[]{"TXT","RTF"});

	public TokenReaderGui(){

		super("Nuevo - Tokenizador");

		//generamos un panel superior para mostrar el documento de entrada y 
		//los tokens de salida
		panelSuperior = new PanelSuperiorGui();
		
		JSplitPane top = panelSuperior.getSplitPane();
		top.setMinimumSize(new Dimension(750,80));
		top.setBorder(null);

		panelErrores = new JTextArea();
		panelErrores.setDoubleBuffered(true);
		panelErrores.setEditable(false);
		panelErrores.setLineWrap(true);
		panelErrores.setMinimumSize(new Dimension(750,80));
	    JScrollPane textAreaErroresScrollPane = new JScrollPane(panelErrores);
		
		JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,top,textAreaErroresScrollPane);
		splitPane.setOneTouchExpandable(true);
		splitPane.setDividerLocation(390);
		
		getContentPane().add(splitPane);

		//barra de menu
		
		//menu archivo
		JMenu menuArchivo = new JMenu();
		menuArchivo.setText("Archivo");

		//menu item abrir
		JMenuItem menuItemAbrir = new JMenuItem();
		menuItemAbrir.setAccelerator(javax.swing.KeyStroke.getKeyStroke(KeyEvent.VK_O,InputEvent.CTRL_MASK));
		menuItemAbrir.setText("Abrir");
		menuItemAbrir.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent evt){
				jMenuItem1ActionPerformed(evt);
			}
		});

		//menu item nuevo
		JMenuItem menuItemNuevo = new JMenuItem();
		menuItemNuevo.setText("Nuevo");
		menuItemNuevo.addActionListener(new java.awt.event.ActionListener(){
			public void actionPerformed(java.awt.event.ActionEvent evt){
				setTitle("Nuevo - Tokenizador");
				clearPaneles();
			}
		});

		menuArchivo.add(menuItemAbrir);
		menuArchivo.add(menuItemNuevo);
		
		JMenu menuTokenizar = new JMenu();
		menuTokenizar.setText("Operaciones");
		
		//menu item abrir
		JMenuItem menuItemTokenizar = new JMenuItem();
		menuItemTokenizar.setAccelerator(javax.swing.KeyStroke.getKeyStroke(KeyEvent.VK_O,InputEvent.CTRL_MASK));
		menuItemTokenizar.setText("Tokenizar");
		menuItemTokenizar.addActionListener(new java.awt.event.ActionListener(){
			
			public void actionPerformed(java.awt.event.ActionEvent evt){
				
				((JComponent)evt.getSource()).setEnabled(false);
				Contexto.getInstance();
				//importante reiniciar el contexto. Al ser persistente si no se reinicia, mantenemos lo 
				//anterior
				Contexto.reset();
				Contexto.appendToBuffer(panelSuperior.getPanelIzquierdo().getText());
				Contexto.setCurrentState(State0.getInstance());
				Contexto.goNext();	
				
				Vector<TokenError> Te = Contexto.getError();
				Vector<Token> TN = Contexto.getTokens();
				SemanticoInicio.setPilaTokens(TN);
				SemanticoInicio.Run();
				panelSuperior.getPanelDerecho().setText("");
				
				int cont=0;
				for (Token tn : TN)
				{
					panelSuperior.getPanelDerecho().append(cont+") "+tn.toString()+"\n");
					cont++;
				}
				
				for (TokenError te : Te)
					panelErrores.append(te.toString()+"\n");
				
				if(panelErrores.getText().length()==0)
					panelErrores.append("Sintaxis OK");
				
				((JComponent)evt.getSource()).setEnabled(true);

			}
		});
		
		menuTokenizar.add(menuItemTokenizar);
		
		jMenuBar1.add(menuArchivo);
		jMenuBar1.add(menuTokenizar);

		setJMenuBar(jMenuBar1);
	}

	private void clearPaneles(){
		panelSuperior.getPanelIzquierdo().setText("");
		panelSuperior.getPanelDerecho().setText("");
		panelErrores.setText("");
	}

	private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt){
		
		chooser = new JFileChooser();
		chooser.setCurrentDirectory(lastFileOpen);
		chooser.setFileFilter(filterFiles);
		
		if(chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
			
			lastFileOpen=chooser.getSelectedFile();
			setTitle(chooser.getSelectedFile().getName() + "- Tokenizador");
			clearPaneles();
			try{
				BufferedReader inBuffer = new BufferedReader(new FileReader(chooser.getSelectedFile().getPath()));
				String linea;
				try{
					while((linea = inBuffer.readLine()) != null)
						panelSuperior.getPanelIzquierdo().append(linea + "\n");
				}catch(IOException e){
					JOptionPane.showMessageDialog(null,"Error de lectura","Message",JOptionPane.WARNING_MESSAGE);
				}
			}catch(FileNotFoundException e){
				JOptionPane.showMessageDialog(null,"Fichero no encontrado","Message",JOptionPane.WARNING_MESSAGE);
			}
		}    
	}

	public void valueChanged(ListSelectionEvent arg0){
		// TODO Auto-generated method stub
	}
	
	public static void main(String[] args){
		javax.swing.SwingUtilities.invokeLater(new Runnable(){
			public void run(){				
				JFrame frame = new TokenReaderGui();
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.pack();
				frame.setSize(800,550);
				frame.setLocationRelativeTo(null);// centrada
				frame.setVisible(true);
			}
		});
	}
	
	public static void setPanelErrores(String Errores) {
		panelErrores.append(Errores+"\n");
	}
}
